package com.cmrx.model.util;

import com.cmrx.model.entity.PictureInfo;

import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;
import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.WritableRaster;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;

public class ImgUtil {

    public static Map<String,Object> drawImage(String orginUrlImgBase64, PictureInfo pictureInfo){
        //画布宽度
        int totleWidth = Integer.valueOf(PropertyUtil.getImageValue("totleWidth").trim());
        //画布高度
        int totleHeight = Integer.valueOf(PropertyUtil.getImageValue("totleHeight").trim());
        //标题字体大小
        int titleFontSize = Integer.valueOf(PropertyUtil.getImageValue("titleFontSize").trim());
        //标题每行最长900,超过换行
        int titleMaxSize = Integer.valueOf(PropertyUtil.getImageValue("titleMaxSize").trim());
        //标题第一行顶部距离
        int titleMagrinTop = Integer.valueOf(PropertyUtil.getImageValue("titleMagrinTop").trim());
        //标题每行间距
        int titleLineHeight = Integer.valueOf(PropertyUtil.getImageValue("titleLineHeight").trim());
        //截取地图图片宽度
        int mapPictureWidth = Integer.valueOf(PropertyUtil.getImageValue("mapPictureWidth").trim());
        //截取地图图片高度
        int mapPictureHeight = Integer.valueOf(PropertyUtil.getImageValue("mapPictureHeight").trim());
        //截取地图图片顶部距离以中心点为基准点
        int mapPictureMagrinTop = Integer.valueOf(PropertyUtil.getImageValue("mapPictureMagrinTop").trim());
        //截取地图图片左边距离以中心点为基准点
        int mapPictureMagrinLeft = Integer.valueOf(PropertyUtil.getImageValue("mapPictureMagrinLeft").trim());
        //指南之偏移量,相对地图
        int tubiaoTop = Integer.valueOf(PropertyUtil.getImageValue("tubiaoTop").trim());
        //指南之偏移量,相对地图
        int tubiaoRight = Integer.valueOf(PropertyUtil.getImageValue("tubiaoRight").trim());
        //表格文字大小
        int tableFontSize = Integer.valueOf(PropertyUtil.getImageValue("tableFontSize").trim());
        //第一行横线距离地图顶部偏移量
        int lineOneTopHeight = Integer.valueOf(PropertyUtil.getImageValue("lineOneTopHeight").trim());
        //第一竖线距离地图偏移量
        int lineOneTopRight = Integer.valueOf(PropertyUtil.getImageValue("lineOneTopRight").trim());
        //线与文字间距
        int lineAndFontHeight = Integer.valueOf(PropertyUtil.getImageValue("lineAndFontHeight").trim());
        //横线数
        int lineCount = Integer.valueOf(PropertyUtil.getImageValue("lineCount").trim());
        //横线最大长度
        int lineMaxWidth = Integer.valueOf(PropertyUtil.getImageValue("lineMaxWidth").trim());

        int targetWidth = Integer.valueOf(PropertyUtil.getImageValue("targetWidth").trim());

        int targetHeight = Integer.valueOf(PropertyUtil.getImageValue("targetHeight").trim());

        String imagePath1 = PropertyUtil.getImageValue("imagePath1").trim();
        String imagePath2 = PropertyUtil.getImageValue("imagePath2").trim();

        BufferedImage bufferedImage =  new BufferedImage(totleWidth, totleHeight, BufferedImage.TYPE_INT_RGB);
        Graphics2D g = (Graphics2D) bufferedImage.getGraphics();

        g.setColor(Color.WHITE);
        g.fillRect(0,0,totleWidth,totleHeight);//填充整个屏幕

        //设置标题字体
        Font siteFont=new Font("微软雅黑", Font.BOLD, titleFontSize);
        g.setFont(siteFont);
        g.setColor(Color.black);
        //处理标题
        int titleWidth = pictureInfo.getTitle().length() * titleFontSize;
        int titleLine = titleWidth/titleMaxSize;
        if(titleLine>0){
            if(titleWidth%titleMaxSize==0){
                titleLine = titleLine;
            }else {
                titleLine = titleLine +1;
            }
        }else {
            titleLine = 1;
        }
        if(titleLine==1){
            int x = (totleWidth - titleWidth)/2;
            g.drawString(pictureInfo.getTitle(),x,titleMagrinTop);
        }else {
            int titleSubLength = pictureInfo.getTitle().length()/titleLine;
            for (int i=1;i<=titleLine;i++){
                int startIndex = 0 + (i-1)*titleSubLength;
                int endIndex = i*titleSubLength;
                String titleContent = pictureInfo.getTitle().substring(startIndex,endIndex);
                if(i==titleLine){
                    titleContent = pictureInfo.getTitle().substring(startIndex,pictureInfo.getTitle().length());
                }
                int x = (totleWidth - titleSubLength*titleFontSize)/2;
                int y = titleMagrinTop + (i-1)*(titleFontSize+titleLineHeight);
                g.drawString(titleContent, x, y);
            }
        }

        //处理地图图片
        BufferedImage image = null;
        try {
            byte[] bytes =Base64.getDecoder().decode(orginUrlImgBase64);
            //转化为输入流
            ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
//            image = ImageIO.read(new File("D:/atemp/ing/"+"1.png"));
            image = ImageIO.read(inputStream);
            inputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        //比较image大小
        int mapHeight = image.getHeight();
        int mapWidth = image.getWidth();
        if(mapPictureWidth>mapWidth){
            mapPictureWidth = mapWidth;
        }
        if(mapPictureHeight>mapHeight){
            mapPictureHeight = mapHeight;
        }
        //截取图片坐标设置
        int mapx = (mapWidth/2) - (mapPictureWidth/2);
        int mapy = (mapHeight/2) - (mapPictureHeight/2) ;
        image = image.getSubimage(mapx,mapy,mapPictureWidth,mapPictureHeight);
        image = ImgUtil.resizeBufferedImage(image,targetWidth,targetHeight,false);

        int magrinx = (totleWidth/2)-(targetWidth/2)-mapPictureMagrinLeft;
        int magriny = (totleHeight/2)-(targetHeight/2)+mapPictureMagrinTop;
        g.drawImage(image,magrinx ,magriny ,null );

        //处理图标图片
        BufferedImage tuBiaoImageOne = null;
        try {
            tuBiaoImageOne = ImageIO.read(new File(imagePath1));
        } catch (IOException e) {
            e.printStackTrace();
        }
        g.drawImage(tuBiaoImageOne,(magrinx+ image.getWidth()+tubiaoRight) ,tubiaoTop ,null );

        //表格处理
        //第一横线处理
        siteFont=new Font("微软雅黑", Font.BOLD, tableFontSize);
        String[] lineNames = {"图例","案发地","案发时间","案发地址","绘制单位","绘图人","绘图时间"};
        g.setFont(siteFont);
        int endY = 0;
        int lineOneY = 0;
        int lineTwoY = 0;
        int lineNameWidth = lineAndFontHeight*3 + tableFontSize*4;
        int inputWidth = lineMaxWidth - lineAndFontHeight*3 - tableFontSize*4- lineAndFontHeight*2;
//        int lineStartX = magrinx + image.getWidth() + lineOneTopRight;
        int lineStartX = totleWidth - lineMaxWidth - lineOneTopRight;
//        int lineStartY = magriny + lineOneTopHeight;
        int lineStartY = tubiaoTop + lineOneTopHeight;
//        int lineEndX = magrinx + image.getWidth() + lineOneTopRight + lineMaxWidth;
        int lineEndX = totleWidth - lineOneTopRight;
        int lineEndY = tubiaoTop + lineOneTopHeight;
        for(int i=1;i<=lineCount;i++) {
            if(i!=1){
                lineStartY = lineStartY + lineAndFontHeight * 3 + tableFontSize;
                lineEndY =lineEndY + lineAndFontHeight * 3 + tableFontSize;
            }
            g.drawLine(lineStartX, lineStartY, lineEndX, lineEndY);
            if(i==1){
                lineOneY = lineEndY;
                g.drawString(lineNames[i-1], lineStartX + lineMaxWidth/2 -tableFontSize - lineAndFontHeight, lineStartY + lineAndFontHeight + tableFontSize);
            }else if(i==2){
                lineTwoY = lineEndY;
                BufferedImage tuBiaoImageTwo = null;
                try {
                    tuBiaoImageTwo = ImageIO.read(new File(imagePath2));
                } catch (IOException e) {
                    e.printStackTrace();
                }
                g.drawImage(tuBiaoImageTwo,lineStartX+(inputWidth-tuBiaoImageTwo.getWidth())/2,lineStartY + lineAndFontHeight  ,null );

                g.drawString(lineNames[i-1], lineStartX + tableFontSize, lineStartY + lineAndFontHeight + tableFontSize);
            }else if(i==3){
                g.drawString(lineNames[i-1], lineStartX + lineAndFontHeight, lineStartY + lineAndFontHeight + tableFontSize);
                g.drawString(pictureInfo.getOccurrence_date_from(), lineStartX+(inputWidth-pictureInfo.getOccurrence_date_from().length()*tableFontSize)/2 + lineNameWidth, lineStartY + lineAndFontHeight + tableFontSize);
            }else if(i==4){
                int valueSizeWidth = pictureInfo.getScene_detail().length()*tableFontSize;
                if(valueSizeWidth>inputWidth){
                    int lineLine = valueSizeWidth/inputWidth;
                    int lineLineCount = lineLine+1;
                    int lineSubLength = pictureInfo.getScene_detail().length()/lineLineCount;
                    g.drawString(lineNames[i-1], lineStartX + lineAndFontHeight, lineStartY + lineAndFontHeight + tableFontSize+(lineLineCount*tableFontSize)/2);
                    for (int x=1;x<=lineLineCount;x++){
                        int startIndex = 0 + (x-1)*lineSubLength;
                        int endIndex = x*lineSubLength;
                        String lineContent = pictureInfo.getScene_detail().substring(startIndex,endIndex);
                        if(x==lineLineCount){
                            lineContent = pictureInfo.getScene_detail().substring(startIndex,pictureInfo.getScene_detail().length());
                        }
                        int lx = lineStartX + lineNameWidth + (inputWidth-lineContent.length()*tableFontSize)/2;
                        if(x!=1){
                            lineStartY = lineStartY +lineAndFontHeight + tableFontSize;
                            lineEndY = lineEndY +lineAndFontHeight + tableFontSize;
                        }
                        g.drawString(lineContent, lx, lineStartY + lineAndFontHeight + tableFontSize);
                    }
                }else {
                    g.drawString(lineNames[i-1], lineStartX + lineAndFontHeight, lineStartY + lineAndFontHeight + tableFontSize);
                    g.drawString(pictureInfo.getScene_detail(), lineStartX +(inputWidth-pictureInfo.getScene_detail().length()*tableFontSize)/2+ lineNameWidth, lineStartY + lineAndFontHeight + tableFontSize);
                }
            }else if(i==5){
                int valueSizeWidth = pictureInfo.getDraw_organize().length()*tableFontSize;
                if(valueSizeWidth>inputWidth){
                    int lineLine = valueSizeWidth/inputWidth;
                    int lineLineCount = lineLine+1;
                    int lineSubLength = pictureInfo.getDraw_organize().length()/lineLineCount;
                    g.drawString(lineNames[i-1], lineStartX + lineAndFontHeight, lineStartY + lineAndFontHeight + tableFontSize +(lineLineCount*tableFontSize)/2);
                    for (int x=1;x<=lineLineCount;x++){
                        int startIndex = 0 + (x-1)*lineSubLength;
                        int endIndex = x*lineSubLength;
                        String lineContent = pictureInfo.getDraw_organize().substring(startIndex,endIndex);
                        if(x==lineLineCount){
                            lineContent = pictureInfo.getDraw_organize().substring(startIndex,pictureInfo.getDraw_organize().length());
                        }
                        int lx = lineStartX + lineNameWidth + (inputWidth-lineContent.length()*tableFontSize)/2;
                        if(x!=1){
                            lineStartY = lineStartY +lineAndFontHeight + tableFontSize;
                            lineEndY = lineEndY +lineAndFontHeight + tableFontSize;
                        }
                        g.drawString(lineContent, lx, lineStartY + lineAndFontHeight + tableFontSize);
                    }
                }else {
                    g.drawString(lineNames[i-1], lineStartX + lineAndFontHeight, lineStartY + lineAndFontHeight + tableFontSize);
                    g.drawString(pictureInfo.getDraw_organize(), lineStartX +(inputWidth-pictureInfo.getDraw_organize().length()*tableFontSize)/2+ lineNameWidth, lineStartY + lineAndFontHeight + tableFontSize);
                }
            }else if(i==6){
                g.drawString(lineNames[i-1], lineStartX + tableFontSize, lineStartY + lineAndFontHeight + tableFontSize);
                g.drawString(pictureInfo.getDraw_person(), lineStartX +(inputWidth-pictureInfo.getDraw_person().length()*tableFontSize)/2+ lineNameWidth, lineStartY + lineAndFontHeight + tableFontSize);
            }else if(i==7){
                g.drawString(lineNames[i-1], lineStartX + lineAndFontHeight, lineStartY + lineAndFontHeight + tableFontSize);
                g.drawString(pictureInfo.getDraw_time(), lineStartX +(inputWidth-pictureInfo.getDraw_time().length()*tableFontSize)/2 + lineNameWidth, lineStartY + lineAndFontHeight + tableFontSize);
            }else {
                endY = lineEndY;
            }
        }
        //竖线
//        int shuStartX = magrinx + image.getWidth() + lineOneTopRight;
        int shuStartX = totleWidth - lineMaxWidth - lineOneTopRight;
        int shuStartY = tubiaoTop + lineOneTopHeight;
//        int shuEndX = magrinx + image.getWidth()+ lineOneTopRight;
        int shuEndX = totleWidth - lineMaxWidth - lineOneTopRight;
        int shuEndY = endY;
        g.drawLine(shuStartX, shuStartY, shuEndX, shuEndY);
        shuStartX =shuStartX + lineAndFontHeight*3 + tableFontSize*4;
        shuStartY = shuStartY + (lineTwoY-lineOneY);
        shuEndX = shuStartX;
        g.drawLine(shuStartX, shuStartY, shuEndX, shuEndY);
//        shuStartX =  magrinx + image.getWidth() + lineOneTopRight + lineMaxWidth;
        shuStartX =  totleWidth-lineOneTopRight;
        shuStartY= tubiaoTop + lineOneTopHeight;
        shuEndX = shuStartX;
        g.drawLine(shuStartX, shuStartY, shuEndX, shuEndY);

   /*     try {
            ImageIO.write(bufferedImage, "png", new File("D:/atemp/ing"+"/"+"test.png"));
        } catch (IOException e) {
            e.printStackTrace();
        }*/

        ByteArrayOutputStream out = new ByteArrayOutputStream();
  /*      try {
            ImageIO.write(bufferedImage, "png", out);
        } catch (IOException e) {
            e.printStackTrace();
        }*/
        out=compressPictureByQality(bufferedImage,0.5f);

        Map<String,Object> resultMap = new HashMap<>();
        resultMap.put("width",bufferedImage.getWidth());
        resultMap.put("heigth",bufferedImage.getHeight());
        resultMap.put("type","png");
        resultMap.put("content",out.toByteArray());
        resultMap.put("suobyte",Html2ImageUtil.createThinPicture(out.toByteArray()));
        return  resultMap;
    }

    /**
     * 调整bufferedimage大小
     * @param source BufferedImage 原始image
     * @param targetW int  目标宽
     * @param targetH int  目标高
     * @param flag boolean 是否同比例调整
     * @return BufferedImage  返回新image
     */
    private static BufferedImage resizeBufferedImage(BufferedImage source, int targetW, int targetH, boolean flag) {
        int type = source.getType();
        BufferedImage target = null;
        double sx = (double) targetW / source.getWidth();
        double sy = (double) targetH / source.getHeight();
        if (flag && sx > sy) {
            sx = sy;
            targetW = (int) (sx * source.getWidth());
        } else if(flag && sx <= sy){
            sy = sx;
            targetH = (int) (sy * source.getHeight());
        }
        if (type == BufferedImage.TYPE_CUSTOM) { // handmade
            ColorModel cm = source.getColorModel();
            WritableRaster raster = cm.createCompatibleWritableRaster(targetW, targetH);
            boolean alphaPremultiplied = cm.isAlphaPremultiplied();
            target = new BufferedImage(cm, raster, alphaPremultiplied, null);
        } else {
            target = new BufferedImage(targetW, targetH, type);
        }
        Graphics2D g = target.createGraphics();
        g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
        g.drawRenderedImage(source, AffineTransform.getScaleInstance(sx, sy));
        g.dispose();
        return target;
    }

    public static ByteArrayOutputStream compressPictureByQality(BufferedImage bufferedImage, float qality){
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        ImageWriter imgWrier;
        ImageWriteParam imgWriteParams;
        imgWrier = ImageIO.getImageWritersByFormatName("jpg").next();
        imgWriteParams = new javax.imageio.plugins.jpeg.JPEGImageWriteParam(null);
        imgWriteParams.setCompressionMode(imgWriteParams.MODE_EXPLICIT);
        imgWriteParams.setCompressionQuality(qality);
        imgWriteParams.setProgressiveMode(imgWriteParams.MODE_DISABLED);
        ColorModel colorModel = bufferedImage.getColorModel();
        imgWriteParams.setDestinationType(new javax.imageio.ImageTypeSpecifier(colorModel, colorModel.createCompatibleSampleModel(32, 32)));
        imgWrier.reset();
        try {
            imgWrier.setOutput(ImageIO.createImageOutputStream(out));
            imgWrier.write(null, new IIOImage(bufferedImage, null, null), imgWriteParams);
            out.flush();
            out.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return out;
    }
}
